#pragma once

#include <iostream>
#include <string>

namespace responsibility {
    
/// @brief 抽象处理者, 定义一个处理请求的接口，包含抽象处理方法和一个后继连接
class AbstractHandler {
public:
    virtual ~AbstractHandler() {}
    virtual void SetNext(AbstractHandler* handler) {
        next_ = handler;
    }
    virtual AbstractHandler* GetNext() {
        return next_;
    }

    virtual void Request(const std::string& state) = 0;

private:
    AbstractHandler* next_ = nullptr;
};

/// @brief 具体处理者, 实现抽象处理者的处理方法，判断能否处理本次请求，如果可以处理请求则处理，否则将该请求转给它的后继者
class ConcreteHandlerA : public AbstractHandler {
public:
    virtual void Request(const std::string& state) {
        if (0 == state.compare("A")) {
            printf("this is ConcreteHandlerA::Request!\n");
        }
        else {
            if (GetNext()) {
                GetNext()->Request(state);
            }
            else {
                printf("From A, Nobody handle this request!\n");
            }
        }
    }
};
class ConcreteHandlerB : public AbstractHandler {
public:
    virtual void Request(const std::string& state) {
        if (0 == state.compare("B")) {
            printf("this is ConcreteHandlerB::Request!\n");
        }
        else {
            if (!GetNext()) {
                GetNext()->Request(state);
            }
            else {
                printf("From B, Nobody handle this request!\n");
            }
        }
    }
};

} // namespace responsibility

void Test_16_chain_of_responsibility_impl_1() {
    printf("-------------------- %s --------------------\n", __FUNCTION__);
    std::shared_ptr<responsibility::AbstractHandler> ptr_A(new responsibility::ConcreteHandlerA());
    std::shared_ptr<responsibility::AbstractHandler> ptr_B(new responsibility::ConcreteHandlerB());

    ptr_A->SetNext(ptr_B.get());
    ptr_A->Request("B");
}

// -------------------- Test_16_chain_of_responsibility_impl_1 --------------------
// this is ConcreteHandlerB::Request!